import requests
import constants
from logger import Logger
import os
import re


def get_card_list():
    """
    获取卡片列表
    通过API请求获取所有已批准的卡片信息
    """
    card_list = []
    # 请求参数
    data = {
        "cardChannel": "cn",           # 卡片频道
        "serviceId": "",               # 服务ID
        "cardId": "",                  # 卡片ID
        "size": 10,                    # 每页条数
        "page": 1,                     # 页码
        "type": "all",                 # 类型
        "cardLevel": 1,                # 卡片等级
        "cardLearningPhase": ""        # 学习阶段
    }

    # 发送首次请求获取总页数
    response = requests.post(constants.GET_APPROVED_CARD_LIST_BY_CATEGORY, data=data, headers=constants.headers)
    max_page = response.json()["pageInfo"]["totalRecords"] // 10 + 1

    # 分页获取所有卡片信息
    for page_num in range(1, max_page + 1):
        data["page"] = page_num
        response = requests.post(constants.GET_APPROVED_CARD_LIST_BY_CATEGORY, data=data, headers=constants.headers)
        cards = response.json()["value"]

        # 提取每张卡片的基本信息
        for card in cards:
            card_info = {
                "cardName": card['cardName'],           # 卡片名称
                "cardDocFileName": card['cardDocFileName']  # 卡片文档文件名
            }
            card_list.append(card_info)
    return card_list


def get_card_document(card_info):
    """
    获取卡片详细文档内容
    :param card_info: 卡片基本信息
    :return: 包含章节内容的完整卡片信息
    """
    # 初始化结果结构
    result = {'cardDocFileName': card_info["cardDocFileName"], 'chapters': [], 'cardName': card_info["cardName"]}

    # 请求参数
    data = {
        'cardDocFileName': card_info["cardDocFileName"],  # 文档文件名
        'cardChannel': "cn"                               # 频道
    }

    # 发送请求获取卡片详细信息
    response = requests.post(constants.QUERY_CARD_INFO, data=data, headers=constants.headers)
    print(card_info['cardName'])

    # 解析章节内容
    content = response.json()['value']['chapterInfoDOList']
    for chapter in content:
        print(chapter['chapterName'])
        print(chapter['content'])
        # 添加章节信息到结果中
        result['chapters'].append({'chapterName': chapter['chapterName'], 'content': chapter['content']})
    return result


def check_sensitive_words(content, sensitive_words_list):
    """
    在内容中检查敏感词汇
    :param content: 要检查的文本内容
    :param sensitive_words_list: 敏感词列表
    :return: 包含找到的敏感词及其位置的列表
    """
    results = []
    for word in sensitive_words_list:
        # 使用正则表达式查找所有匹配位置（忽略大小写）
        positions = [m.start() for m in re.finditer(word, content, re.IGNORECASE)]
        if positions:
            results.append((word, positions))
    return results


def scan_codelab_for_sensitive_words(sensitive_words_list):
    """
    扫描所有Codelab文档以查找敏感词汇
    :param sensitive_words_list: 敏感词列表
    """
    print(f'敏感词汇列表：{sensitive_words_list}')
    print('_' * 50)

    # 获取所有卡片列表
    cards = get_card_list()
    to_be_checked = []

    # 获取每个卡片的详细文档
    for card in cards:
        to_be_checked.append(get_card_document(card))

    print(f'待检测的卡片数：{len(to_be_checked)}')
    print(f'开始检测敏感词汇...')

    found_count = 0  # 记录发现敏感词的次数

    # 遍历每个卡片进行敏感词检测
    for card in to_be_checked:
        print(f'正在检测：{card["cardDocFileName"]}')

        # 遍历每个章节
        for chapter in card['chapters']:
            # 使用正则表达式查找敏感词汇
            sensitive_found = check_sensitive_words(chapter['content'], sensitive_words_list)

            if sensitive_found:
                found_count += 1
                print(f'发现敏感词汇：')
                # 输出找到的敏感词信息
                for word, positions in sensitive_found:
                    print(f'敏感词汇：{word}，卡片名称：{card["cardName"]}，章节名称：{chapter["chapterName"]}')
                    logging.warning(f'敏感词汇：{word}，卡片名称：{card["cardName"]}，章节名称：{chapter["chapterName"]}')
            else:
                print(f'章节名称：{chapter["chapterName"]},未发现敏感词汇')
        print('_' * 50)

    print(f'敏感词汇检测完成，共发现{found_count}个敏感词汇')
    input('请按任意键退出...')


def main():
    """
    主函数：获取用户输入的敏感词并执行扫描
    """
    # 设置敏感词汇列表
    sensitive_words_input = input("请输入敏感词汇，多个词汇请用英文逗号分割：").strip()
    sensitive_words_list = [word.strip() for word in sensitive_words_input.split(",")] if sensitive_words_input else []

    # 执行扫描
    scan_codelab_for_sensitive_words(sensitive_words_list)


if __name__ == '__main__':
    logging = Logger(os.getcwd())  # 初始化日志记录器
    main()

